package com.huilian.iotbox.data.utils;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.parser.Feature;
import com.huilian.iotbox.data.config.AgencyConfig;
import com.huilian.iotbox.data.config.MiddlewareConfig;
import com.huilian.iotbox.data.controller.ControllerException;
import com.huilian.iotbox.data.enums.FunctionEnum;
import com.huilian.iotbox.data.po.RequestModel;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpRequestBase;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.ObjectUtils;


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.HttpURLConnection;
import java.net.URL;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Map;

/**
 * @author 谢洛涛
 * @date 2021/1/9 15:46
 */
@Slf4j
public class HttpUtils {

    public static String format(AgencyConfig agencyConfig,Object reqParam, FunctionEnum functionEnum) {
        RequestModel requestModel = createRequestModel(agencyConfig,reqParam, functionEnum);
        String body = JSON.toJSONString(requestModel);
        log.info("请求的内容：{}", body);
        String sign = RsaUtil.sign(body, agencyConfig.getPrivateKey());
        requestModel.setSign(sign);
        return JSON.toJSONString(requestModel);
    }

    private static RequestModel createRequestModel(AgencyConfig agencyConfig,Object reqParam, FunctionEnum functionEnum) {
        RequestModel requestModel = new RequestModel();
        requestModel.setAgencyNo(agencyConfig.getIsvOrgId());
        requestModel.setTimestamp(new Timestamp(System.currentTimeMillis()).toString());
        requestModel.setFunction(functionEnum.getCode());
        requestModel.setContent(JSON.toJSONString(reqParam));
        requestModel.setPayCompany("helipay");
        return requestModel;
    }

    public static String format(AgencyConfig agencyConfig,Object reqParam, FunctionEnum functionEnum, String payCompanyCode) {
        RequestModel requestModel = createRequestModel(agencyConfig,reqParam, functionEnum);
        requestModel.setPayCompany(payCompanyCode);
        String body = JSON.toJSONString(requestModel);
        log.info(functionEnum.getCode() + "请求的内容：{}", body);
        String sign = RsaUtil.sign(body, agencyConfig.getPrivateKey());
        requestModel.setSign(sign);
        return JSON.toJSONString(requestModel);
    }

    // 目前测试使用，请不要正式调用到
    public static String format2(AgencyConfig agencyConfig,Object reqParam, FunctionEnum functionEnum, String payCompanyCode) {
        RequestModel requestModel = new RequestModel();
        requestModel.setAgencyNo(agencyConfig.getIsvOrgId());
        requestModel.setTimestamp(new Timestamp(System.currentTimeMillis()).toString());
        requestModel.setFunction(functionEnum.getCode());
        requestModel.setContent(JSON.toJSONString(reqParam));
        requestModel.setPayCompany(payCompanyCode);
        requestModel.setRsaType("00");
        String body = JSON.toJSONString(requestModel);
        log.info(functionEnum.getCode() + "请求的内容：{}", body);
        String sign = RsaUtil.sign(body, agencyConfig.getPrivateKey());
        requestModel.setSign(sign);
        return JSON.toJSONString(requestModel);
    }


    /**
     * 自己请求中间件 代付模块
     * */
    public static String formatDaifu(AgencyConfig agencyConfig,Object reqParam,String function) {
        RequestModel requestModel = new RequestModel();
        requestModel.setTimestamp(new Timestamp(System.currentTimeMillis()).toString());
        requestModel.setFunction(function);
        requestModel.setContent(JSON.toJSONString(reqParam));
        String body = JSON.toJSONString(requestModel);
        String sign = RsaUtil.sign(body, agencyConfig.getDaiFu_rsa_privateKey());
        requestModel.setSign(sign);
        return JSON.toJSONString(requestModel);
    }

    /**
     * GET不带数据请求
     *
     * @param url
     * @return
     * @throws IOException
     */
    public static String httpGet(String url) {
        HttpGet httpGet = new HttpGet(url);
        return getJsonObject(httpGet);
    }

    /**
     * POST带数据请求
     *
     * @param url
     * @param data
     * @return
     */
    public static String httpPost(String url, String data) {
        HttpPost httpPost = new HttpPost(url);
        StringEntity postEntity = new StringEntity(data, "UTF-8");
        httpPost.setEntity(postEntity);
        return getJsonObject(httpPost);
    }

    public static String httpReq(String reqUrl, String param) throws IOException {
        URL url = new URL(reqUrl);
        HttpURLConnection httpsConn = (HttpURLConnection) url.openConnection();
        httpsConn.setConnectTimeout(8000);// 设置连接主机超时
        httpsConn.setReadTimeout(8000);// 设置从主机读取数据超时
        httpsConn.setDoOutput(true);
        httpsConn.setRequestMethod("POST");
        httpsConn.setRequestProperty("Content-Type", "application/xml;charset=UTF-8");
        httpsConn.setRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 5.0; Windows NT; DigExt)");
        httpsConn.setRequestProperty("Content-Length", String.valueOf(param.length()));

        OutputStreamWriter out = new OutputStreamWriter(httpsConn.getOutputStream(), "UTF-8");
        out.write(param);
        out.flush();
        out.close();

        BufferedReader reader = new BufferedReader(new InputStreamReader(
                httpsConn.getInputStream(), "UTF-8"));
        String tempLine = "";
        StringBuffer resultBuffer = new StringBuffer();
        while ((tempLine = reader.readLine()) != null) {
            resultBuffer.append(tempLine).append(System.getProperty("line.separator"));
        }
        return resultBuffer.toString();
    }

    /**
     * 获取请求里的JsonObject
     *
     * @param request sonObject
     * @return
     */
    private static String getJsonObject(HttpRequestBase request) {
        CloseableHttpClient client = HttpClients.createDefault();
        try {
            //接收 发送请求返回对象
            HttpResponse response = client.execute(request);
            //拿结果
            HttpEntity entity = response.getEntity();
            if (entity != null) {
                return EntityUtils.toString(entity, "UTF-8");
            }
        } catch (IOException e) {
            log.error("请求发起失败!", e);
            e.printStackTrace();
        } finally {
            //连接释放
            request.releaseConnection();
        }
        return null;
    }

    /**
     * 通过请求返回的内容进行验签
     *
     * @param response
     * @return
     */
    public static Map<String, Object> getResultData(String response) {
        log.info("请求返回的内容：{}", response);
        Map<String, Object> result = JSON.parseObject(response, Feature.OrderedField);
        final String sign = (String) result.get("sign");
        result.remove("sign");
        final String content = JSON.toJSONString(result);
        if (!RsaUtil.verifySign(content, sign, MiddlewareConfig.PublicKey)) {
            log.info("验签失败");
            throw new ControllerException("验签失败");
        }
        return result;
    }

    /**
     * @param response 返回响应解签
     * */
    public static boolean verifyResponseSign(String response){
        //排序转换成JSONObject
        JSONObject json = JSONObject.parseObject(response, Feature.OrderedField);
        final String sign =(String)json.get("sign");
        System.out.println("返回报文"+json);
        json.remove("sign");
        if (RsaUtil.verifySign(JSON.toJSONString(json),sign,  MiddlewareConfig.PublicKey)) {
            log.info("------------验签成功！-------------"+json);
            return true;
        }
        return false;
    }

    public static String repPhone(String phone){
        return stringConvert(phone,3,7);
    }
    /**
     * 将传递过来的字符串设置为***
     * 包左不包右
     * @param param 传递过来的字符串
     * @param start 开始替换位置
     * @param end 替换结束位置
     * */
    public static String stringConvert(String param,Integer start,Integer end){
        StringBuilder result1 = new StringBuilder(param);
        int rep = end - start;
        StringBuilder replaceStr = new StringBuilder();
        for (int i = 0;i<rep;i++){
            replaceStr.append("*");
        }
        return result1.replace(start,end,replaceStr.toString()).toString();
    }


    /**
     * @param object 传递过来的类型
     * 将String类型转换为Integer类型
     * */
    public static Integer IntegerConvert(Object object){
        String str = (String)object;
        if(ObjectUtils.isEmpty(str)){
            return null;
        }
        return Integer.parseInt(str);
    }


    public static String getOutTradeNo() {
        Date date = new Date();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmssSSS");
        StringBuffer sb = new StringBuffer();
        String dateStr = sdf.format(date);
        int ranNum = (int) ((Math.random() * 9 + 1) * 1000);
        return sb.append(dateStr).append(ranNum).toString();
    }

    public static String getRandomString(int stringLength) {
        String string = "abcdefghijklmnopqrstuvwxyz";
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < stringLength; i++) {
            int index = (int) Math.floor(Math.random() * string.length());//向下取整0-25
            sb.append(string.charAt(index));
        }
        return sb.toString().toUpperCase();
    }

    public static String formatPay(AgencyConfig agencyConfig, Object reqParam, FunctionEnum functionEnum, String payCompanyCode) {
        RequestModel requestModel = createRequestModelPay(agencyConfig,reqParam, functionEnum,payCompanyCode);
        String body = JSON.toJSONString(requestModel);
        log.info("请求的内容：{}", body);
        String sign = RsaUtil.sign(body, agencyConfig.getPrivateKey());
        requestModel.setSign(sign);
        return JSON.toJSONString(requestModel);
    }

    private static RequestModel createRequestModelPay(AgencyConfig agencyConfig, Object reqParam, FunctionEnum functionEnum,String payCompanyCode) {
        RequestModel requestModel = new RequestModel();
        requestModel.setAgencyNo(agencyConfig.getIsvOrgId());
        requestModel.setTimestamp(new Timestamp(System.currentTimeMillis()).toString());
        requestModel.setFunction(functionEnum.getCode());
        requestModel.setContent(JSON.toJSONString(reqParam));
        requestModel.setPayCompany(payCompanyCode);
        return requestModel;
    }
}
